# 开发一个仿照 Flutter 的UI库，这里仅提供以下教学网站中提供的控件，你可以提供其它控件。
# 参考 https://flutter.cn/docs/get-started/flutter-for/web-devs

import time
import json


def maketag(tag, attrs=None, style=None):
    elt = javascript.document.createElement(tag)
    if attrs is not None:
        for k, v in attrs.items():
            elt.setAttribute(k, v)
    if style is not None:
        style = ';'.join([f'{k}:{v}' for k, v in style.items()])
        elt.setAttribute('style', style)
    return elt

def add_id(elt, *ids):
	id0 = elt.getAttribute('id').data()
	if id0 is None:
		id0 = set()
	else:
		id0 = set(id0.split())

	for c in ids:
		id0.add(c)
	elt.setAttribute('id', ' '.join(id0))

def add_class(elt, *classes):
    classes0 = elt.getAttribute('class').data()
    if classes0 is None:
        classes0 = set()
    else:
        classes0 = set(classes0.split())
    for c in classes:
        classes0.add(c)
    elt.setAttribute('class', ' '.join(classes0))


def remove_class(elt, *classes):
    classes0 = elt.getAttribute('class').data()
    if classes0 is None:
        classes0 = set()
    else:
        classes0 = set(classes0.split())
    for c in classes:
        classes0.remove(c)
    elt.setAttribute('class', ' '.join(classes0))

def _make_svg(tag, attrs):
    xmlns = 'http://www.w3.org/2000/svg'
    elt = javascript.document.createElementNS(xmlns, tag)
    for k,v in attrs.items():
        elt.setAttribute(k,v)
    return elt


from . import flutter_colors

Colors = flutter_colors.Colors


class EdgeInsets:
    def __init__(self, sizes):
        assert isinstance(sizes, (tuple, list))
        self.sizes = sizes

    def __repr__(self):
        return ' '.join([f'{s}px' if isinstance(s, int) else s for s in self.sizes])

    def all(sizes):
        return EdgeInsets([sizes])

    def only(top=0, right=0, bottom=0, left=0):
        return EdgeInsets([top, right, bottom, left])

    def symmetric(horizontal=0, vertical=0):
        return EdgeInsets([vertical, horizontal, vertical, horizontal])


class BorderRadius:
    def __init__(self, sizes):
        assert isinstance(sizes, (tuple, list))
        self.sizes = sizes

    def __repr__(self):
        return ' '.join([f'{s}px' if isinstance(s, int) else s for s in self.sizes])

    def all(sizes):
        return BorderRadius([sizes])

    def only(top=0, right=0, bottom=0, left=0):
        return BorderRadius([top, right, bottom, left])


class LinearGradient:
    def __init__(self, degree, colors):
        assert isinstance(degree, (int, str))
        assert isinstance(colors, (tuple, list)) and (len(colors) == 2)
        for c in colors:
            assert isinstance(c, str)
        self.degree = degree
        self.colors = colors

    def __repr__(self):
        degree = f'{self.degree}deg' if isinstance(self.degree, int) else self.degree
        return f'linear-gradient({degree}, {self.colors[0]}, {self.colors[1]})'


class Offset:
    def __init__(self, x, y):
        assert isinstance(x, int)
        assert isinstance(y, int)
        self.x = x
        self.y = y


class BoxShadow:
    def __init__(self, color, offset, blurRadius):
        assert isinstance(color, str)
        assert isinstance(offset, Offset)
        assert isinstance(blurRadius, int)
        self.color = color
        self.offset = offset
        self.blurRadius = blurRadius

    def __repr__(self):
        x = self.offset.x
        y = self.offset.y
        blurRadius = self.blurRadius
        if isinstance(x, int): x = f'{x}px'
        if isinstance(y, int): y = f'{y}px'
        if isinstance(blurRadius, int): blurRadius = f'{blurRadius}px'
        return f'{x} {y} {blurRadius} {self.color}'


class BoxShape:
    circle = 'circle'


class Container:
    def __init__(self, child, width=None, height=None, color=None, borderRadius=None,
                 gradient=None, padding=None, margin=None, boxShadow=None, shape=None):
        assert hasattr(child, 'render') and callable(child.render)
        assert (width is None) or (isinstance(width, (int, str)))
        assert (height is None) or (isinstance(height, (int, str)))
        assert (color is None) or (isinstance(color, str))
        assert (borderRadius is None) or (isinstance(borderRadius, BorderRadius))
        assert (gradient is None) or (isinstance(gradient, LinearGradient))
        assert (padding is None) or (isinstance(padding, EdgeInsets))
        assert (margin is None) or (isinstance(margin, EdgeInsets))
        if boxShadow is not None:
            assert isinstance(boxShadow, (tuple, list))
            for b in boxShadow:
                assert isinstance(b, BoxShadow)
        assert (shape is None) or (isinstance(shape, str))
        self.child = child
        self.width = width
        self.height = height
        self.color = color
        self.borderRadius = borderRadius
        self.gradient = gradient
        self.padding = padding
        self.margin = margin
        self.boxShadow = boxShadow
        self.shape = shape

    def render(self):
        style = {}
        if self.width is not None:
            style['width'] = f'{self.width}px' if isinstance(self.width, int) else self.width
        if self.height is not None:
            style['height'] = f'{self.height}px' if isinstance(self.height, int) else self.height
        if self.color is not None:
            style['background-color'] = self.color
        if self.padding is not None:
            style['padding'] = str(self.padding)
        if self.margin is not None:
            style['margin'] = str(self.margin)
        if self.borderRadius is not None:
            style['border-radius'] = str(self.borderRadius)
        if self.gradient is not None:
            style['background'] = str(self.gradient)
        if self.boxShadow is not None:
            style['box-shadow'] = ', '.join([str(b) for b in self.boxShadow])
        if self.shape is not None:
            if self.shape == 'circle':
                style['border-radius'] = '50%'
        if hasattr(self.child, 'textAlign'):
            if self.child.textAlign is not None:
                style['text-align'] = self.child.textAlign
        e = maketag('div', style=style)
        e.appendChild(self.child.render())
        return e


class FontWeight:
    w100 = '100'
    w200 = '200'
    w300 = '300'
    w400 = '400'
    w500 = '500'
    w600 = '600'
    w700 = '700'
    w800 = '800'
    w900 = '900'


class FontStyle:
    italic = 'italic'


class TextStyle:
    def __init__(self, fontSize=None, fontWeight=None, fontFamily=None,
                 letterSpacing=None, fontStyle=None):
        assert (fontSize is None) or isinstance(fontSize, (int, str))
        assert (fontWeight is None) or isinstance(fontWeight, str)
        assert (fontFamily is None) or isinstance(fontFamily, str)
        assert (letterSpacing is None) or (isinstance(letterSpacing, (int, str)))
        assert (fontStyle is None) or (isinstance(fontStyle, str))
        self.fontSize = fontSize
        self.fontWeight = fontWeight
        self.fontFamily = fontFamily
        self.letterSpacing = letterSpacing
        self.fontStyle = fontStyle

    def __repr__(self):
        style = []
        if self.fontWeight is not None:
            style.append(self.fontWeight)
        if self.fontSize is not None:
            style.append(f'{self.fontSize}px' if isinstance(self.fontSize, int) else self.fontSize)
        if self.fontFamily is not None:
            style.append(self.fontFamily)
        return ' '.join(style)


class TextAlign:
    center = 'center'
    left = 'left'
    right = 'right'


class TextOverflow:
    clip = 'clip'
    ellipsis = 'ellipsis'


class Text:
    def __init__(self, text, color=None, textAlign=None, style=None,
                 overflow=TextOverflow.clip, maxLines=None):
        assert (textAlign is None) or (isinstance(textAlign, str))
        assert (style is None) or (isinstance(style, TextStyle))
        assert (color is None) or (isinstance(color, str))
        assert isinstance(overflow, str)
        if maxLines is not None:
            assert isinstance(maxLines, int)
            assert maxLines >= 1
        self.text = text
        self.color = color
        self.textAlign = textAlign
        self.style = style
        self.overflow = overflow
        self.maxLines = maxLines

    def render(self):
        style = {}
        if self.style is not None:
            style['font'] = str(self.style)
            if self.style.letterSpacing is not None:
                letterSpacing = self.style.letterSpacing
                if isinstance(letterSpacing, int):
                    letterSpacing = f'{letterSpacing}px'
                style['letter-spacing'] = letterSpacing
            if self.style.fontStyle is not None:
                style['font-style'] = self.style.fontStyle
        if self.color is not None:
            style['color'] = self.color
        if self.maxLines is not None:
            style['overflow'] = 'hidden'
            style['text-overflow'] = self.overflow
            style['display'] = '-webkit-box'
            style['-webkit-line-clamp'] = self.maxLines
            style['-webkit-box-orient'] = 'vertical'
        e = maketag('div', style=style)
        p = javascript.document.createTextNode(self.text)
        e.appendChild(p)
        return e


class RichText:
    def __init__(self, text):
        assert isinstance(text, TextSpan)
        self.text = text

    def render(self):
        return self.text.render()


class TextSpan:
    def __init__(self, text=None, color=None, style=None, children=None):
        assert (text is not None) or (children is not None)
        assert (color is None) or (isinstance(color, str))
        assert (style is None) or isinstance(style, TextStyle)
        if text is not None:
            assert isinstance(text, str)
        if children is not None:
            assert isinstance(children, (tuple, list))
            for c in children:
                assert isinstance(c, TextSpan)
        self.text = text
        self.color = color
        self.style = style
        self.children = children

    def render(self):
        style = {}
        if self.style is not None:
            style['font'] = str(self.style)
            if self.style.letterSpacing is not None:
                letterSpacing = self.style.letterSpacing
                if isinstance(letterSpacing, int):
                    letterSpacing = f'{letterSpacing}px'
                style['letter-spacing'] = letterSpacing
            if self.style.fontStyle is not None:
                style['font-style'] = self.style.fontStyle
        if self.color is not None:
            style['color'] = self.color
        e = maketag('span', style=style)
        if self.text is not None:
            p = javascript.document.createTextNode(self.text)
            e.appendChild(p)
        elif self.children is not None:
            for c in self.children:
                e.appendChild(c.render())
        return e


class Center:
    # def __init__(self, child):
    #     assert hasattr(child, 'render') and callable(child.render)
    #     self.child = child
    #
    # def render(self):
    #     e = maketag('div', style={'display': 'flex', 'align-items': 'center',
    #                               'justify-content': 'center', 'width': '100%', 'height': '100%'})
    #     e.appendChild(self.child.render())
    #     return e
    def __init__(self, children):
        assert isinstance(children, (tuple, list))
        for child in children:
            assert hasattr(child, 'render') and callable(child.render)
        self.children = children

    def render(self):
        e = maketag('div', style={'display': 'flex', 'align-items': 'center', 'flex-flow': 'column',
                                  'justify-content': 'center', 'width': '100%', 'height': '100%'})
        for child in self.children:
            e.appendChild(child.render())
        return e

class Children:
    def __init__(self, children):
        assert isinstance(children, (tuple, list))
        for child in children:
            assert hasattr(child, 'render') and callable(child.render)
        self.children = children

    def render(self):
        e = maketag('div', style={'display': 'flex', 'flex-flow': 'column', 'width': '100%', 'height': '100%'})
        for child in self.children:
            e.appendChild(child.render())
        return e


class Stack:
    def __init__(self, children):
        assert isinstance(children, (tuple, list))
        for c in children:
            assert isinstance(c, Positioned)
        self.children = children

    def render(self):
        e = maketag('div', style={'position': 'relative'})
        for c in self.children:
            e.appendChild(c.render())
        return e


class Positioned:
    def __init__(self, child, left, top, color=None):
        assert hasattr(child, 'render') and callable(child.render)
        assert isinstance(left, (int, str))
        assert isinstance(top, (int, str))
        self.child = child
        self.left = left
        self.top = top
        self.color = color

    def render(self):
        top = f'{self.top}px' if isinstance(self.top, int) else self.top
        left = f'{self.left}px' if isinstance(self.left, int) else self.left
        e = maketag('div', style={'position': 'absolute', 'top': top, 'left': left, 'color':f'{self.color}'})
        e.appendChild(self.child.render())
        return e


class Transform:
    def __init__(self, child, rotate=None, scale=None):
        assert hasattr(child, 'render') and callable(child.render)
        assert (rotate is None) or isinstance(rotate, (int, str))
        assert (scale is None) or isinstance(scale, float)
        self.child = child
        self.rotate = rotate
        self.scale = scale

    def render(self):
        transform = []
        if self.rotate is not None:
            rotate = f'{self.rotate}deg' if isinstance(self.rotate, int) else self.rotate
            transform.append(f'rotate({rotate})')
        if self.scale is not None:
            transform.append(f'scale({self.scale})')
        e = maketag('div')
        if len(transform) > 0:
            e.style.transform = ' '.join(transform)
        e.appendChild(self.child.render())
        return e


# https://www.cnblogs.com/hellocd/p/10443237.html

class Axis:  # flex-direction
    horizontal = 'row'
    vertical = 'column'


class MainAxisAlignment:  # justify-content
    center = 'center'
    end = 'flex-end'
    spaceAround = 'space-around'
    spaceBetween = 'space-between'
    spaceEvenly = 'space-evenly'
    start = 'flex-start'


class CrossAxisAlignment:  # align-items
    baseline = 'baseline'
    center = 'center'
    end = 'end'
    start = 'start'
    stretch = 'stretch'


class MainAxisSize:
    max = 'max'
    min = 'min'


class Flex:
    def __init__(self, children, direction,
                 mainAxisAlignment=MainAxisAlignment.start,
                 crossAxisAlignment=CrossAxisAlignment.center,
                 mainAxisSize=MainAxisSize.min):
        assert isinstance(children, (tuple, list))
        for child in children:
            assert hasattr(child, 'render') and callable(child.render), type(child).__name__
        self.children = children
        assert direction in (Axis.horizontal, Axis.vertical)
        assert mainAxisAlignment in (MainAxisAlignment.center,
                                     MainAxisAlignment.end,
                                     MainAxisAlignment.spaceAround,
                                     MainAxisAlignment.spaceBetween,
                                     MainAxisAlignment.spaceEvenly,
                                     MainAxisAlignment.start)
        assert crossAxisAlignment in (CrossAxisAlignment.baseline,
                                      CrossAxisAlignment.center,
                                      CrossAxisAlignment.end,
                                      CrossAxisAlignment.start,
                                      CrossAxisAlignment.stretch)
        assert mainAxisSize in (MainAxisSize.max,
                                MainAxisSize.min)
        self.direction = direction
        self.mainAxisAlignment = mainAxisAlignment
        self.crossAxisAlignment = crossAxisAlignment
        self.mainAxisSize = mainAxisSize

    def render(self):
        style = {'display': 'flex',
                 'flex-direction': self.direction,
                 'flex-wrap': 'nowrap',
                 'justify-content': self.mainAxisAlignment,
                 'align-items': self.crossAxisAlignment}
        if self.mainAxisSize == MainAxisSize.max:
            if self.direction == 'row':
                style['width'] = '100%'
            else:
                style['height'] = '100%'
        e = maketag('div', style=style)
        for child in self.children:
            e.appendChild(child.render())
        return e


class Row(Flex):
    def __init__(self, children,
                 mainAxisAlignment=MainAxisAlignment.start,
                 crossAxisAlignment=CrossAxisAlignment.center,
                 mainAxisSize=MainAxisSize.min):
        super(Row, self).__init__(children,
                                  direction=Axis.horizontal,
                                  mainAxisAlignment=mainAxisAlignment,
                                  crossAxisAlignment=crossAxisAlignment,
                                  mainAxisSize=mainAxisSize)


class Column(Flex):
    def __init__(self, children,
                 mainAxisAlignment=MainAxisAlignment.start,
                 crossAxisAlignment=CrossAxisAlignment.center,
                 mainAxisSize=MainAxisSize.min):
        super(Column, self).__init__(children,
                                     direction=Axis.vertical,
                                     mainAxisAlignment=mainAxisAlignment,
                                     crossAxisAlignment=crossAxisAlignment,
                                     mainAxisSize=mainAxisSize)


# MDC (Material Design Components)

class Scaffold:
    def __init__(self, appBar, body):
        assert hasattr(appBar, 'render') and callable(appBar.render)
        assert hasattr(body, 'render') and callable(body.render)
        self.appBar = appBar
        self.body = body

    def render(self):
        scafflod_height = javascript.document.documentElement.clientHeight.data()
        e = maketag('div', style={'display': 'flex', 'flex-flow': 'column',
                                  'height': '200%'})  # 'height': f'{scafflod_height}px'
        header = maketag('header', {'class': 'mdc-top-app-bar mdc-top-app-bar--fixed'},
                         style={'flex': '0 1 auto'})
        e.appendChild(header)
        main = maketag('header', {'class': 'mdc-top-app-bar--fixed-adjust'},
                       style={'flex': '1 1 auto'})
        e.appendChild(main)
        header.appendChild(self.appBar.render())
        main.appendChild(self.body.render())
        self.topAppBar = javascript.mdc.topAppBar.MDCTopAppBar.new(e)
        return e


class AppBar:
    def __init__(self, leading=None, title=None, actions=None):
        if leading is not None:
            assert hasattr(leading, 'render') and callable(leading.render)
        if title is not None:
            assert hasattr(title, 'render') and callable(title.render)
        if actions is not None:
            assert isinstance(actions, (tuple, list))
            for action in actions:
                assert hasattr(action, 'render') and callable(action.render)
        self.leading = leading
        self.title = title
        self.actions = actions

    def render(self):
        e = maketag('div', {'class': 'mdc-top-app-bar__row'})
        start = maketag('header', {'class': 'mdc-top-app-bar__section mdc-top-app-bar__section--align-start'})
        e.appendChild(start)
        end = maketag('header',
                      {'class': 'mdc-top-app-bar__section mdc-top-app-bar__section--align-end', 'rule': 'toolbar'})
        e.appendChild(end)
        if self.leading is not None:
            leading = self.leading.render()
            add_class(leading, 'mdc-top-app-bar__navigation-icon')
            start.appendChild(leading)
        if self.title is not None:
            title = self.title.render()
            add_class(title, 'mdc-top-app-bar__title')
            start.appendChild(title)
        if self.actions is not None:
            for action in self.actions:
                action = action.render()
                add_class(action, 'mdc-top-app-bar__action-item')
                end.appendChild(action)
        return e


class IconButton:
    def __init__(self, icon, onPressed=None):
        assert isinstance(icon, Icon)
        if onPressed is not None:
            assert callable(onPressed)
        self.icon = icon
        self.onPressed = onPressed

    def render(self):
        e = maketag('button', {'class': 'material-icons mdc-top-app-bar__action-item mdc-icon-button'})
        e.appendChild(javascript.document.createTextNode(self.icon.icon))
        rip = maketag('span', {'class': 'mdc-button__ripple'})
        e.appendChild(rip)
        if self.onPressed is not None:
            e.bind('click', self.onPressed)
        javascript.mdc.ripple.MDCRipple.new(e)
        return e


class Icon:
    def __init__(self, icon, href=None):
        assert isinstance(icon, str)
        self.icon = icon
        self.href=href

    def render(self):
        e = maketag('span', {'class': 'material-icons'})
        e.appendChild(javascript.document.createTextNode(self.icon))
        if self.href is not None:
            hr = maketag('a', {'href': f'{self.href}'}, style={'text-decoration': 'none'})
            hr.appendChild(e)
            return hr
        return e


from . import flutter_icons

Icons = flutter_icons.Icons


####


"""
Banners: by-LJ
"""
class MaterialBanner:
    def __init__(self, content=None, leading=None, actions=None):
        if content is not None:
            assert hasattr(content, 'render') and callable(content.render)
        if leading is not None:
            assert isinstance(leading, Icon)
        if actions is not None:
            assert isinstance(actions, (tuple, list))
            for action in actions:
                assert hasattr(action, 'render') and callable(action.render)
        self.content = content
        self.leading = leading
        self.actions = actions

    def render(self):
        e = maketag('div', {'class': 'mdc-banner', 'role': 'banner'},
                    style={'display': 'flex', 'flex-flow': 'column', 'width': '100%',
                           'justify-content': ''})
        con = maketag('div', {'class': 'mdc-banner__content', 'role': 'alertdialog', 'aria-live': 'assertive'},
                      style={'flex-wrap': 'wrap', 'justify-content': 'center'})
        e.appendChild(con)
        gtext = maketag('div', {'class': 'mdc-banner__graphic-text-wrapper'})
        con.appendChild(gtext)

        if self.leading is not None:
            graphic = maketag('div', {'class': 'mdc-banner__graphic', 'role': 'img'})
            icon = maketag('i', {'class': 'material-icons mdc-banner__icon'})
            icon.appendChild(javascript.document.createTextNode(self.leading.icon))
            graphic.appendChild(icon)
            gtext.appendChild(graphic)
        cont = maketag('div', {'class': 'mdc-banner__text'})
        gtext.appendChild(cont)
        if self.content is not None:
            cont.appendChild(self.content.render())
        if self.actions is not None:
            for action in self.actions:
                action = action.render()
                add_class(action, 'mdc-banner__actions')
                con.appendChild(action)
        # javascript.mdc.banner.MDCBanner.new(e)
        return e

# class CircleAvatar:
#     def __init__(self, child = None):
#         assert isinstance(child, Icon)
#         self.child = child
#     def render(self):
#         return
class FlatButton:
    def __init__(self, child, onPressed, href=None):
        assert isinstance(child, Text)
        if onPressed is not None:
            assert callable(onPressed)
        self.child = child
        self.onPressed = onPressed
        self.href = href

    def render(self):
        e = maketag('button', {'class': 'mdc-button mdc-banner__primary-action'})
        e.appendChild(self.child.render())
        rip = maketag('span', {'class': 'mdc-button__ripple'})
        e.appendChild(rip)
        if self.onPressed is not None:
            e.bind('click', self.onPressed)
        if self.href is not None:
            hr = maketag('a', {'href':f'{self.href}'}, style={'text-decoration': 'none'})
            hr.appendChild(e)
            return hr
        javascript.mdc.ripple.MDCRipple.new(e)
        return e


"""
Bottom-Navigation: NO
"""


"""
Buttons: by-LJ
"""
class TextButton:
    def __init__(self, onPressed=None, icon=None, label=None, href=None):
        self.onPressed = onPressed
        if icon is not None:
            assert isinstance(icon, Icon)
            self.icon = icon
        if label is not None:
            assert isinstance(label, Text)
            self.label = label
        self.href = href

    def render(self):
        tb = maketag('div', {'class': 'mdc-touch-target-wrapper'}, style={'display': 'flex'})
        butt = maketag('button', {'class': 'mdc-button mdc-button--touch'})
        rip = maketag('span', {'class': 'mdc-button__ripple'})
        but_tou = maketag('span', {'class': 'mdc-button__touch'})
        if self.icon is not None:
            ic = maketag('i', {'class': 'material-icons mdc-button__icon', 'aria-hidden': 'true'})
            ic.appendChild(javascript.document.createTextNode(self.icon.icon))
        if self.label is not None:
            la = maketag('span', {'class': 'mdc-button__label'})
            la.appendChild(self.label.render())
        butt.appendChild(rip)
        butt.appendChild(but_tou)
        butt.appendChild(ic)
        butt.appendChild(la)
        tb.appendChild(butt)
        if self.href is not None:
            hr = maketag('a', {'href':f'{self.href}'}, style={'text-decoration': 'none'})
            hr.appendChild(tb)
            return hr
        return tb

class OutlinedButton:
    def __init__(self, onPressed=None, icon=None, label=None, href=None):
        self.onPressed = onPressed
        if icon is not None:
            assert isinstance(icon, Icon)
            self.icon = icon
        if label is not None:
            assert isinstance(label, Text)
            self.label = label
        self.href = href

    def render(self):
        butt = maketag('button', {'class': 'mdc-button mdc-button--outlined mdc-button--icon-leading'},
                       style={'display': 'flex'})
        rip = maketag('span', {'class': 'mdc-button__ripple'})
        if self.icon is not None:
            ic = maketag('i', {'class': 'material-icons mdc-button__icon', 'aria-hidden': 'true'})
            ic.appendChild(javascript.document.createTextNode(self.icon.icon))
        if self.label is not None:
            la = maketag('span', {'class': 'mdc-button__label'})
            la.appendChild(self.label.render())
        butt.appendChild(rip)
        butt.appendChild(ic)
        butt.appendChild(la)
        if self.href is not None:
            hr = maketag('a', {'href':f'{self.href}'}, style={'text-decoration': 'none'})
            hr.appendChild(butt)
            return hr
        return butt

class ContainedButton:
    def __init__(self, onPressed=None, icon=None, label=None, href=None):
        self.onPressed = onPressed
        if icon is not None:
            assert isinstance(icon, Icon)
            self.icon = icon
        if label is not None:
            assert isinstance(label, Text)
            self.label = label
        self.href = href

    def render(self):
        butt = maketag('button', {'class': 'mdc-button mdc-button--raised mdc-button--leading'},
                       style={'display': 'flex'})
        rip = maketag('span', {'class': 'mdc-button__ripple'})
        if self.icon is not None:
            ic = maketag('i', {'class': 'material-icons mdc-button__icon', 'aria-hidden': 'true'})
            ic.appendChild(javascript.document.createTextNode(self.icon.icon))
        if self.label is not None:
            la = maketag('span', {'class': 'mdc-button__label'})
            la.appendChild(self.label.render())
        butt.appendChild(rip)
        butt.appendChild(ic)
        butt.appendChild(la)
        if self.href is not None:
            hr = maketag('a', {'href':f'{self.href}'}, style={'text-decoration': 'none'})
            hr.appendChild(butt)
            return hr
        return butt


"""
Cards: by-LJ
"""
# class Padding:
class Card:
    def __init__(self, clipBehavior=None, priActions=None, actions=None):
        self.clipBehavior = clipBehavior
        if priActions is not None:
            assert isinstance(priActions, (tuple, list))
            for preAct in priActions:
                assert hasattr(preAct, 'render') and callable(preAct.render)
        self.priActions = priActions
        if actions is not None:
            assert hasattr(actions, 'render') and callable(actions.render)
        self.actions = actions

    def render(self):
        card = maketag('div', {'class': 'mdc-card'},
                       style={'width': '500px', 'height': '150px', 'text-align': 'center'})
        pri_act = maketag('div', {'class': 'mdc-card__primary-action'})
        if self.priActions is not None:
            media = maketag('div', {'class': 'mdc-card__media mdc-card__media--square'})
            media_con = maketag('div', {'class': 'mdc-card__media-content'})
            for priAct in self.priActions:
                media_con.appendChild(priAct.render())
            media.appendChild(media_con)
        rip = maketag('div', {'class': 'mdc-card__ripple'})
        pri_act.appendChild(media)
        pri_act.appendChild(rip)

        acts = maketag('div', {'class': 'mdc-card__actions'})
        if self.actions is not None:
            acts.appendChild(self.actions.render())

        card.appendChild(pri_act)
        card.appendChild(acts)
        return card

class ButtonBar:
    def __init__(self, alignment=None, children=None):
        self.alignment = alignment
        if children is not None:
            assert isinstance(children, (tuple, list))
            for child in children:
                assert hasattr(child, 'render') and callable(child.render)
        self.children = children

    def render(self):
        act_but = maketag('div', {'class': 'mdc-card__action-buttons'})
        if self.children is not None:
            for child in self.children:
                act_but.appendChild(child.render())
        return act_but


"""
Checkboxes: by-LXX+WYN+LZG
"""
# class CheckBox:
#     def __init__(self,
#                  onChanged=None,
#                  tristate=None,
#                  value=None,
#                  activeColor=None,
#                  text=None,
#                  mainAxisAlignment=None,
#                  disab=None
#                  ):
#         if onChanged is not None:
#             assert hasattr(onChanged, 'render') and callable(onChanged.render)
#         # if tristate is not None:
#         # 	assert callable(tristate)
#         # if value is not None:
#         # 	assert callable(value)
#         # if activeColor is not None:
#         # 	assert(callable(activeColor))
#         # if text is not None:
#         # 	assert hasattr(text, 'render') and callable(text.render)
#         # if mainAxisAlignment is not None:
#         # 	assert hasattr(mainAxisAlignment, 'render') and callable(mainAxisAlignment.render)
#
#         # assert isinstance(actions, (tuple,list))
#         # for action in actions:
#         #	assert hasattr(action, 'render') and callable(action.render)
#         self.onChanged = onChanged
#         self.tristate = tristate
#         self.value = value
#         self.activeColor = activeColor
#         self.text = text
#         self.mainAxisAlignment = mainAxisAlignment
#         self.disa = disab
#
#     def render(self):
#         e = maketag('div', {'class': 'mdc-form-field'})
#         start = None
#
#         if self.disa is not None:
#             start = maketag('div', {'class': 'mdc-mdc-checkbox mdc-checkbox--disabled'})
#         else:
#             start = maketag('div', {'class': 'mdc-checkbox'})
#         e.appendChild(start)
#
#         end = maketag('label', {'for': 'checkbox-1'})
#         if self.text is not None:
#             end.appendChild(self.text.render())
#         e.appendChild(end)
#
#         inputEle = maketag('input', {'type': 'checkbox', 'class': 'mdc-checkbox__native-control', 'id': 'checkbox-1'})
#
#         start.appendChild(inputEle)
#
#         backgroundEle = maketag('div', {'class': 'mdc-checkbox__background'})
#         start.appendChild(backgroundEle)
#
#         svgEle = maketag('svg', {'class': 'mdc-checkbox__checkmark', 'viewBox': '0 0 24 24'})
#         backgroundEle.appendChild(svgEle)
#
#         pathEle = maketag('path', {'class': 'mdc-checkbox__checkmark-path', 'fill': 'None',
#                                    'd': 'M1.73,12.91 8.1,19.28 22.79,4.59'})
#         svgEle.appendChild(pathEle)
#
#         mixedmarkEle = maketag('div', {'class': 'mdc-checkbox__mixedmark'})
#         backgroundEle.appendChild(mixedmarkEle)
#
#         rippleEle = maketag('div', {'class': 'mdc-checkbox__ripple'})
#         start.appendChild(rippleEle)
#
#         return e
#
class DisabledCheckBox:
    def __init__(self,
                 onChanged=None,
                 tristate=None,
                 value=None,
                 activeColor=None,
                 text=None,
                 mainAxisAlignment=None):
        if onChanged is not None:
            assert hasattr(onChanged, 'render') and callable(onChanged.render)
        # if tristate is not None:
        # 	assert callable(tristate)
        # if value is not None:
        # 	assert callable(value)
        # if activeColor is not None:
        # 	assert(callable(activeColor))
        # if text is not None:
        # 	assert hasattr(text, 'render') and callable(text.render)
        # if mainAxisAlignment is not None:
        # 	assert hasattr(mainAxisAlignment, 'render') and callable(mainAxisAlignment.render)

        # assert isinstance(actions, (tuple,list))
        # for action in actions:
        #	assert hasattr(action, 'render') and callable(action.render)
        self.onChanged = onChanged
        self.tristate = tristate
        self.value = value
        self.activeColor = activeColor
        self.text = text
        self.mainAxisAlignment = mainAxisAlignment

    def render(self):
        e = maketag('div', {'class': 'mdc-form-field'})

        start = maketag('div', {'class': 'mdc-mdc-checkbox mdc-checkbox--disabled'})
        e.appendChild(start)

        end = maketag('label', {'for': 'basic-disabled-checkbox', 'id': 'basic-disabled-checkbox-label'})
        end.appendChild(javascript.document.createTextNode(self.text))
        e.appendChild(end)

        inputEle = maketag('input', {
            'type': 'checkbox',
            'class': 'mdc-checkbox__native-control',
            'id': 'basic-disabled-checkbox-label',
            'disabled': ''
        })

        start.appendChild(inputEle)

        backgroundEle = maketag('div', {'class': 'mdc-checkbox__background'})
        start.appendChild(backgroundEle)

        svgEle = maketag('svg', {'class': 'mdc-checkbox__checkmark', 'viewBox': '0 0 24 24'})
        backgroundEle.appendChild(svgEle)

        pathEle = maketag('path', {'class': 'mdc-checkbox__checkmark-path', 'fill': 'None',
                                   'd': 'M1.73,12.91 8.1,19.28 22.79,4.59'})
        svgEle.appendChild(pathEle)

        mixedmarkEle = maketag('div', {'class': 'mdc-checkbox__mixedmark'})
        backgroundEle.appendChild(mixedmarkEle)

        rippleEle = maketag('div', {'class': 'mdc-checkbox__ripple'})
        start.appendChild(rippleEle)

        return e

# class Check_box:
# 	def __init__(self,id,name):
# 		self.id = id
# 		self.name = name
# 	def render(self):
# 		e = maketag('div', {'class':'mdc-form-field'})
# 		start = maketag('div', {'class':'mdc-checkbox'})
# 		e.appendChild(start)
# 		in_put = maketag('input', {'type':"checkbox",'class':"mdc-checkbox__native-control",'id':self.id})
# 		start.appendChild(in_put)
# 		background = maketag('div',{'class':'mdc-checkbox__background'})
# 		start.appendChild(background)
# 		svg = maketag('svg',{'class': 'mdc-checkbox__checkmark', 'viewBox': '0 0 24 24'})
# 		background.appendChild(svg)
# 		path = maketag('path', {'class': 'mdc-checkbox__checkmark-path',
#                                   'fill': "none", 'd': 'M1.73,12.91 8.1,19.28 22.79,4.59'})
# 		svg.appendChild(path)
# 		mixedmark = maketag('div', {'class': 'mdc-checkbox__mixedmark'})
# 		background.appendChild(mixedmark)
# 		ripple = maketag('div', {'class': 'mdc-checkbox__ripple'})
# 		start.appendChild(ripple)
# 		end = javascript.document.createTextNode(self.name)
# 		e.appendChild(end)
# 		return e

'''
by-LZG
'''

class CheckBox:
    def __init__(self, onChanged, tristate, value=False, activeColor=Colors.black, id='checkbox'):
        assert isinstance(onChanged, bool)
        if tristate is not None:
            assert isinstance(tristate, bool)
        if value is not None:
            assert isinstance(value, bool)
        if activeColor is not None:
            assert isinstance(activeColor, str)
        assert isinstance(id, str)
        self.onChanged = onChanged
        self.tristate = tristate
        self.value = value
        self.activeColor = activeColor
        if id == 'checkbox':
            self.checkBoxId = 'checkbox-' + str(time.time())
        else:
            self.checkBoxId = id

    def render(self):
        e = maketag('div', {'class': 'mdc-form-field'})
        mdcCheckbox = maketag('div', {'class': 'mdc-checkbox'})
        e.appendChild(mdcCheckbox)
        checkbox = maketag('input', {'type': 'checkbox',
                                     'class': 'mdc-checkbox__native-control',
                                     'id': self.checkBoxId},
                           {'color': self.activeColor})
        if not self.onChanged:
            checkbox.setAttribute('disabled', 'true')
        if self.value:
            checkbox.setAttribute('checked', "true")
        checkbox.setAttribute('data-indeterminate', "true" if self.tristate else "false")
        mdcCheckbox.appendChild(checkbox)
        mdcCheckboxBackground = maketag('div', {'class': 'mdc-checkbox__background'})
        mdcCheckbox.appendChild(mdcCheckboxBackground)
        svg = _make_svg('svg', {'class': 'mdc-checkbox__checkmark', 'viewBox': '0 0 24 24'})
        mdcCheckboxBackground.appendChild(svg)
        path = _make_svg('path', {'class': 'mdc-checkbox__checkmark-path',
                                  'fill': "none", 'd': 'M1.73,12.91 8.1,19.28 22.79,4.59'})
        svg.appendChild(path)
        mdcCheckboxMixedmark = maketag('div', {'class': 'mdc-checkbox__mixedmark'})
        mdcCheckboxBackground.appendChild(mdcCheckboxMixedmark)
        mdcCheckboxRipple = maketag('div', {'class': 'mdc-checkbox__ripple"'})
        mdcCheckbox.appendChild(mdcCheckboxRipple)
        javascript.mdc.checkbox.MDCCheckbox.new(mdcCheckbox)
        return e

"""
Chips: by-LZW+LJ
"""
class Chips:
    def __init__(self, children=None):
        if children is not None:
            assert isinstance(children, (tuple, list))
            for child in children:
                assert hasattr(child, 'render') and callable(child.render)
        self.children = children

    def render(self):
        ichip = maketag('span', {'class': 'mdc-evolution-chip-set', 'role': 'grid'})
        pre = maketag('span', {'class': 'mdc-evolution-chip-set__chips', 'role': 'presentation'},
                      style={'display': 'flex'})
        ichip.appendChild(pre)
        if self.children is not None:
            for child in self.children:
                pre.appendChild(child.render())
        return ichip

class InputChip:
    def __init__(self, avatar=None, label=None, onSelected=False):
        if avatar is not None:
            assert isinstance(avatar, Icon)
        self.avatar = avatar
        if label is not None:
            assert isinstance(label, Text)
        self.label = label
        self.onSelected = onSelected

    def render(self):
        mec = maketag('span', {'class': 'mdc-evolution-chip', 'role': 'row'})
        mecc = maketag('span',
                       {'class': 'mdc-evolution-chip__cell mdc-evolution-chip__cell--primary', 'role': 'gridcell'})
        mec.appendChild(mecc)
        butt = maketag('button',
                       {'class': 'mdc-evolution-chip__action mdc-evolution-chip__action--primary', 'type': 'button',
                        'tabindex': '0'}, style={'display': 'flex', 'align-items': 'center'})
        # rip = maketag('span', {'class': 'mdc-evolution-chip__ripple mdc-evolution-chip__ripple--primary'})
        rip = maketag('span', {'class': 'mdc-button__ripple'})
        butt.appendChild(rip)
        if self.avatar is not None:
            ava = maketag('span', {'class': 'material-icons mdc-button__icon', 'aria-hidden': 'true'})
            ava.appendChild(javascript.document.createTextNode(self.avatar.icon))
        butt.appendChild(ava)
        if self.label is not None:
            lab = maketag('span', {'class': 'mdc-evolution-chip__text-label'})
            lab.appendChild(self.label.render())
        butt.appendChild(lab)
        mecc.appendChild(butt)
        return mec

class ChoiceChip:
    def __init__(self, label=None, selected=None):
        if label is not None:
            assert hasattr(label, 'render') and callable(label.render)
        self.label = label
        self.selected = selected

    def render(self):
        e = maketag('span', {'class': 'mdc-evolution-chip-set', 'role': 'grid'})

        start = maketag('span', {'class': 'mdc-evolution-chip-set__chips', 'role': 'presentation'})

        # <span class="mdc-evolution-chip" role="row" id="c0">
        start_level0 = maketag('span', {'class': 'mdc-evolution-chip', 'role': 'row', 'id': 'c0'})

        start_level0_1 = maketag('span', {'class': 'mdc-evolution-chip__cell mdc-evolution-chip__cell--primary',
                                          'role': 'gridcell'})

        start_level0_2 = maketag('button', {'class': 'mdc-evolution-chip__action mdc-evolution-chip__action--primary',
                                            'type': 'button', 'tabindex': '0'})

        start_level0_3 = maketag('span', {'class': 'mdc-evolution-chip__ripple mdc-evolution-chip__ripple--primary'})
        start_level0_2.appendChild(start_level0_3)

        if self.label is not None:
            label = self.label.render()
            add_class(label, 'mdc-evolution-chip__text-label')
            start_level0_2.appendChild(label)

        start_level0_1.appendChild(start_level0_2)
        start_level0.appendChild(start_level0_1)
        start.appendChild(start_level0)

        e.appendChild(start)

        return e

class RemoveButton:
    def __init__(self, text, id, onClick=False):
        self.onClick = onClick
        self.text = Text(text, color='#EFEFEF')
        self.id = 'b' + str(id)

    def render(self):
        e = maketag('button', {'id': self.id},
                    style={'width': '18px',
                           'height': '18px',
                           'border-radius': '50%',  # 圆形
                           'background-color': '#5B5B5B',
                           'border-style': 'none',  # 去边框
                           }
                    )
        e.appendChild(self.text.render())

        def remove(ev):
            style1 = {'width': '18px',
                      'height': '18px',
                      'border-radius': '50%',  # 圆形
                      'background-color': '#000000',
                      'border-style': 'none',  # 去边框
                      }
            style1 = ';'.join([f'{k}:{v}' for k, v in style1.items()])
            e.setAttribute('style', style1)
            time.sleep(0.1)
            b1 = javascript.document.getElementById(self.id)
            d1 = b1.parentNode.parentNode
            d1.parentNode.removeChild(d1)

        if self.onClick == True:
            e.bind('click', remove)
        javascript.mdc.ripple.MDCRipple.new(e)
        return e

id = 0

class Chip:
    def __init__(self, text, thumbnail=None, remove=False, filter=False):
        assert isinstance(text, Text)
        if thumbnail is not None:
            assert isinstance(thumbnail, Icon)
        global id
        child = []
        if thumbnail is not None:
            child.append(thumbnail)
        child.append(Container(child=text, padding=EdgeInsets.only(6, 8, 6, 8)))
        self.id = 'c' + str(id)
        id = id + 1
        if remove == True:
            child.append(RemoveButton('x', id=id, onClick=True))
        self.row = Row(children=child)
        if filter == True:
            child_new = []
            for c in child:
                child_new.append(c)
            child_new.insert(0, Icon(Icons.done))
            self.row_new = Row(children=child_new)
        self.filter = filter
        self.working = False
        self.is_down = False
        self.md_x = 0
        self.md_y = 0

    def render(self):
        e = maketag('span', {'class': 'mdc-evolution-chip-set', 'role': 'grid'})
        a1 = maketag('span', {'class': 'mdc-evolution-chip-set__chips', 'role': 'presentation'})
        e.appendChild(a1)
        a2 = maketag('span', {'class': 'mdc-evolution-chip', 'role': 'row'})
        a1.appendChild(a2)
        a3 = maketag('span',
                     {'class': 'mdc-evolution-chip__cell mdc-evolution-chip__cell--primary', 'role': 'gridcell'})
        a2.appendChild(a3)
        b = maketag('button', {'id': self.id},
                    style={'border-radius': '15px',
                           'background-color': 'white',
                           # 'border-color':'#000000',
                           }
                    )
        b.appendChild(self.row.render())
        a3.appendChild(b)

        def down(ev):
            c = javascript.document.getElementById(self.id)
            self.is_down = True
            m_down_x = json.loads(ev.pageX)
            m_down_y = json.loads(ev.pageY)
            dx = json.loads(c.offsetLeft)
            dy = json.loads(c.offsetTop)
            self.md_x = m_down_x - dx
            self.md_y = m_down_y - dy

        def move(ev):
            c = javascript.document.getElementById(self.id)
            dx = json.loads(c.offsetLeft)
            dy = json.loads(c.offsetTop)
            m_move_x = json.loads(ev.pageX)
            m_move_y = json.loads(ev.pageY)
            if self.is_down == True:
                ev.stopPropagation()
                ndx = m_move_x - self.md_x
                ndy = m_move_y - self.md_y
                style = {'border-radius': '15px',
                         'background-color': '#D7D7D7',
                         'position': 'absolute',
                         'left': str(ndx) + 'px', 'top': str(ndy) + 'px'}
                style = ';'.join([f'{k}:{v}' for k, v in style.items()])
                c.setAttribute('style', style)

        def up(ev):
            self.is_down = False

        if self.filter == False:
            e.bind('mousedown', down)
            e.bind('mouseup', up)
            e.bind('mousemove', move)

        def filter(ev):
            if self.working == False:
                c = javascript.document.getElementById(self.id)
                c.parentNode.removeChild(c)
                b_new = maketag('button', {'id': self.id},
                                style={'border-radius': '15px',
                                       'background-color': '#B7B7B7',
                                       # 'border-color':'#000000',
                                       }
                                )
                b_new.appendChild(self.row_new.render())
                a3.appendChild(b_new)
                self.working = True
            else:
                c = javascript.document.getElementById(self.id)
                c.parentNode.removeChild(c)
                a3.appendChild(b)
                self.working = False

        if self.filter == True:
            e.bind('click', filter)
        javascript.mdc.ripple.MDCRipple.new(e)

        return e


"""
Data-Pickers: NO
"""


"""
Data-Tables: by-LXZ+HLH
"""
'''
by-LXZ
'''
class PaginatedDataTable:
    def __init__(self, header=None, tableheads=None, tablebodys=None, width=None, isdigits=None):
        if header is not None:
            assert hasattr(header, 'render') and callable(header.render)
        if tableheads is not None:
            assert isinstance(tableheads, list)
        if tablebodys is not None:
            assert isinstance(tablebodys, list)
            for tablebody in tablebodys:
                assert isinstance(tablebody, list)

        assert (width is None) or (isinstance(width, (int, str)))
        assert (isdigits is None) or (isinstance(isdigits, list))
        self.header = header
        self.tableheads = tableheads
        self.tablebodys = tablebodys
        self.width = width
        self.isdigits = isdigits

    def render(self):
        style = {}
        if self.width is not None:
            style['width'] = f'{self.width}px' if isinstance(self.width, int) else self.width
        e = maketag('div', {'class': 'mdc-data-table'}, style=style)  # style={'width': '100%'}
        tcontainer = maketag('div', {'class': 'mdc-data-table__table-container'})
        table = maketag('table', {'class': 'mdc-data-table__table', 'aria-label': 'Dessert calories'})
        head = maketag('thead')
        trhead = maketag('tr', {'class': 'mdc-data-table__header-row'})

        count = 0
        if self.tableheads is not None:
            for tablehead in self.tableheads:
                if self.isdigits[count]:
                    newhead = maketag('th',
                                      {'class': 'mdc-data-table__header-cell mdc-data-table__header-cell--numeric',
                                       'role': 'columnheader', 'scope': 'col'})
                else:
                    newhead = maketag('th',
                                      {'class': 'mdc-data-table__header-cell', 'role': 'columnheader', 'scope': 'col'})
                newhead.appendChild(javascript.document.createTextNode(tablehead))
                trhead.appendChild(newhead)
                count = count + 1

        body = maketag('tbody', {'class': 'mdc-data-table__content'})
        trbody = maketag('tr', {'class': 'mdc-data-table__row'})
        if self.tablebodys is not None:
            for tablebody in self.tablebodys:
                count = 0
                trbody = maketag('tr', {'class': 'mdc-data-table__row'})
                for tb in tablebody:
                    if count == 0:
                        if self.isdigits[count]:
                            newbody = maketag('th', {'class': 'mdc-data-table__cell mdc-data-table__cell--numeric',
                                                     'scope': 'row'})
                        else:
                            newbody = maketag('th', {'class': 'mdc-data-table__cell', 'scope': 'row'})
                    else:
                        if self.isdigits[count]:
                            newbody = maketag('td', {'class': 'mdc-data-table__cell mdc-data-table__cell--numeric'})
                        else:
                            newbody = maketag('td', {'class': 'mdc-data-table__cell'})
                    newbody.appendChild(javascript.document.createTextNode(tb))
                    trbody.appendChild(newbody)
                    count = count + 1
                body.appendChild(trbody)

        head.appendChild(trhead)
        table.appendChild(head)
        table.appendChild(body)
        tcontainer.appendChild(table)
        e.appendChild(tcontainer)
        return e

'''
by-HLH
'''
class DataTable:
    def __init__(self, columns):
        assert hasattr(columns, 'render') and callable(columns.render)

        self.columns = columns

    def render(self):
        e = maketag('duv', {'class': 'mdc-data-table'})
        table = maketag('table', {'class': 'mdc-data-table__table'})
        e.appendChild(table)
        columns = self.columns.render()
        # e.appendChild(rows)
        thead = maketag('thead', {'class': 'mdc-data-table__header'})
        thead.appendChild(columns)
        table.appendChild(thead)

        return e


"""
Dialogs: by-LYX+XY
"""
'''
by-LYX
'''
class AlertDialog:
    def __init__(self, title, content, actions):
        if title is not None:
            assert hasattr(title, 'render') and callable(title.render)
        if content is not None:
            assert hasattr(content, 'render') and callable(content.render)
        if actions is not None:
            assert isinstance(actions, (tuple, list))
            for action in actions:
                assert hasattr(action, 'render') and callable(action.render)

        self.title = title
        self.content = content
        self.actions = actions

    def render(self):
        e = maketag('div', {'class': 'mdc-dialog'})

        # container = maketag('div', {'class':'mdc-dialog__container'})
        container = maketag('div', {
            'style': 'display:flex;justify-content: center; align-items:center;margin:auto;width: 200px;height: 100%;'})
        e.appendChild(container)

        scrim = maketag('div', {'class': 'mdc-dialog__scrim'})
        e.appendChild(scrim)

        surface = maketag('div', {'class': 'mdc-dialog__surface', 'role': 'alertdialog', 'aria-modal': 'true',
                                  'aria-labelledby': 'my-dialog-title', 'aria-describedby': 'my-dialog-content'})
        container.appendChild(surface)

        if self.title is not None:
            title = self.title.render()
            add_class(title, 'mdc-dialog__title')
            add_id(title, 'my-dialog-title')
            surface.appendChild(title)

        # if self.content is not None:
        # 	content = self.content.render()
        # 	add_class(content, 'mdc-dialog__content')
        # 	add_id(content, 'my-dialog-content')
        # 	surface.appendChild(content)

        actionDiv = maketag('div', {'class': 'mdc-dialog__actions'})
        surface.appendChild(actionDiv)
        if self.actions is not None:
            for action in self.actions:
                action = action.render()
                add_class(action, 'mdc-button mdc-dialog__button')
                actionDiv.appendChild(action)

        return container

class Button:
    def __init__(self, onPressed=None, child=None, href=None):
        assert hasattr(child, 'render') and callable(child.render)

        if onPressed is not None:
            assert callable(onPressed)

        self.onPressed = onPressed
        self.child = child
        self.href = href

    def render(self):
        e = maketag('button', {'class': 'mdc-button mdc-dialog__button', 'type': "button"})

        ripple = maketag('div', {'class': 'mdc-button__ripple'})
        e.appendChild(ripple)
        e.appendChild(self.child.render())

        if self.onPressed is not None:
            e.bind('click', self.onPressed)
        if self.href is not None:
            hr = maketag('a', {'href': f'{self.href}'}, style={'text-decoration': 'none'})
            hr.appendChild(e)
            return hr
        return e

'''
by-XY
'''
class Dialog:
    def __init__(self, header):
        self.e = maketag('div', {'class': 'mdc-dialog mdc-dialog--open'})
        con = maketag('div', {'class': 'mdc-dialog__container'})
        self.e.appendChild(con)
        self.sur = maketag('div', {'class': 'mdc-dialog__surface',
                                   'role': 'alertdialog', 'aria-modal': "true"})
        con.appendChild(self.sur)

        if header is not None:
            assert hasattr(header, 'render') and callable(header.render)
            title = maketag('h2', {'class': 'mdc-dialog__title'})
            title.appendChild(
                javascript.document.createTextNode(header.text))
            self.sur.appendChild(title)
        pass


class AlertDialog(Dialog):
    def __init__(self, title=None, content=None, actions=None):
        super(AlertDialog, self).__init__(title)
        if content is not None:
            assert hasattr(content, 'render') and callable(content.render)
        if actions is not None:
            assert isinstance(actions, (tuple, list))
            for action in actions:
                assert hasattr(action, 'render') and callable(action.render)
        self.title = title
        self.content = content
        self.actions = actions
        pass

    def render(self):
        if self.content is not None:
            content = self.content.render()
            add_class(content, 'mdc-dialog__content')
            self.sur.appendChild(content)
        if self.actions is not None:
            acts = maketag('div', {'class': 'mdc-dialog__actions'})
            self.sur.appendChild(acts)
            for action in self.actions:
                action = action.render()
                acts.appendChild(action)
        scrim = maketag('div', {'class': 'mdc-dialog__scrim'})
        self.e.appendChild(scrim)
        return self.e


# class FlatButton:
#     def __init__(self, textColor, child, onPressed=None):
#         assert isinstance(textColor, Color)
#         if child is not None:
#             assert hasattr(child, 'render') and callable(child.render)
#         if onPressed is not None:
#             assert callable(onPressed)
#         self.textColor = textColor
#         self.child = child
#         self.onPressed = onPressed
#         pass
#
#     def render(self):
#         e = maketag('button', {'class': 'mdc-button mdc-dialog__button'})
#         ripple = maketag('div', {'class': 'mdc-button__ripple'})
#         e.appendChild(ripple)
#         text = maketag('span', {'class': 'mdc-button__label'},
#                        {'color': '#'+self.textColor.color[4:]})
#         text.appendChild(javascript.document.createTextNode(self.child.text))
#         e.appendChild(text)
#         if self.onPressed is not None:
#             e.bind('click', self.onPressed)
#         return e


class Color:
    def __init__(self, color):
        assert isinstance(color, str)
        self.color = color
        pass
class SimpleDialog(Dialog):
    def __init__(self, title, children):
        super(SimpleDialog, self).__init__(title)
        if children is not None:
            assert isinstance(children, (tuple, list))
            for child in children:
                assert hasattr(child, 'render') and callable(child.render)
        self.title = title
        self.chidlren = children
        self.ul = maketag('ul', {'class': 'mdc-list mdc-list--avatar-list'})
        self.cont = maketag(
            'div', {'class': 'mdc-dialog__content'}, {'padding': '0 8px'})
        pass

    def render(self):
        if self.chidlren is not None:
            self.sur.appendChild(self.cont)
            self.cont.appendChild(self.ul)
            for child in self.chidlren:
                self.ul.appendChild(child.render())
        scrim = maketag('div', {'class': 'mdc-dialog__scrim'})
        self.e.appendChild(scrim)
        return self.e

class SimpleDialogItem:
    def __init__(self, icon, color, text, onPressed):
        if icon is not None:
            assert isinstance(icon, Icon)
        if color is not None:
            assert isinstance(color, str)
        if text is not None:
            assert isinstance(text, str)
        if onPressed is not None:
            assert callable(onPressed)

        self.icon = icon
        self.color = color
        self.text = text
        self.onPressed = onPressed
        pass

    def render(self):
        li = maketag('li', {'class': 'mdc-list-item', 'data-mdc-dialog-action': self.text},
                     {'height': '56px', 'padding-left': '12px', 'align-items': 'center'})
        li.appendChild(maketag('span', {'class': 'mdc-list-item__ripple'}))
        icon = self.icon.render(
            {'font-size': '48px', 'padding-right': '12px', 'color': self.color})
        add_class(icon, 'mdc-list-item__graphic')
        li.appendChild(icon)
        text = maketag('span', {'class': 'mdc-list-item__text'})
        text.appendChild(javascript.document.createTextNode(self.text))
        li.appendChild(text)
        return li

class ConfirmationDialog(SimpleDialog):
    def __init__(self, title, children, actions):
        super(ConfirmationDialog, self).__init__(title, children)
        if actions is not None:
            assert isinstance(actions, (tuple, list))
            for action in actions:
                assert hasattr(action, 'render') and callable(action.render)
        self.actions = actions
        self.cont = maketag('div', {'class': 'mdc-dialog__content'},
                            {'padding': '0 8px', 'border-top': '1px solid lightgrey',
                             'border-bottom': '1px solid lightgrey'})
        pass

    def render(self):
        e = super(ConfirmationDialog, self).render()
        remove_class(self.ul, "mdc-list--avatar-list")
        if self.actions is not None:
            acts = maketag('div', {'class': 'mdc-dialog__actions'})
            self.sur.appendChild(acts)
            for action in self.actions:
                action = action.render()
                acts.appendChild(action)
        return e

first_radio_choice = True

class RadioChoiceItem:
    def __init__(self, text):
        if text is not None:
            assert isinstance(text, str)
        self.text = text
        pass

    def render(self):
        li = maketag('li', {'class': 'mdc-list-item'},
                     {'padding-left': '12px', 'align-items': 'center'})
        span = maketag('span', {'class': 'mdc-list-item__graphic'})
        li.appendChild(span)
        radio = maketag('div', {'class': 'mdc-radio'})
        span.appendChild(radio)
        inp = None
        global first_radio_choice
        if first_radio_choice:
            inp = maketag('input', {'class': 'mdc-radio__native-control', 'id': self.text,
                                    'name': 'radio-group', 'type': 'radio', 'checked': 'true'})
            first_radio_choice = False
        else:
            inp = maketag('input', {'class': 'mdc-radio__native-control', 'id': self.text,
                                    'name': 'radio-group', 'type': 'radio'})
        radio.append(inp)
        radio_background = maketag('div', {'class': 'mdc-radio__background'})
        radio.append(radio_background)
        radio_background.appendChild(
            maketag('div', {'class': 'mdc-radio__outer-circle'}))
        radio_background.appendChild(
            maketag('div', {'class': 'mdc-radio__inner-circle'}))
        label = maketag('label', {'for': self.text,
                                  'class': 'mdc-list-item__text'})
        label.appendChild(javascript.document.createTextNode(self.text))
        li.appendChild(label)
        return li

class FullScreenDialog:
    def __init__(self, title, children, actions):
        if title is not None:
            assert hasattr(title, 'render') and callable(title.render)
        if children is not None:
            assert isinstance(children, (tuple, list))
            for child in children:
                assert hasattr(child, 'render') and callable(child.render)
        if actions is not None:
            assert isinstance(actions, (tuple, list))
            for action in actions:
                assert hasattr(action, 'render') and callable(action.render)
        self.title = title
        self.children = children
        self.actions = actions
        pass

    def render(self):
        e = maketag(
            'div', {'class': 'mdc-dialog mdc-dialog--open mdc-dialog--fullscreen'})
        con = maketag('div', {'class': 'mdc-dialog__container'})
        e.appendChild(con)
        sur = maketag('div', {'class': 'mdc-dialog__surface',
                              'role': 'dialog', 'aria-modal': "true"})
        con.appendChild(sur)

        header = maketag('div', {'class': 'mdc-dialog__header'})
        sur.appendChild(header)
        title = maketag('h2', {'class': 'mdc-dialog__title'})
        title.appendChild(javascript.document.createTextNode(self.title.text))
        header.appendChild(title)
        close_btn = maketag(
            'button', {'class': 'mdc-icon-button material-icons mdc-dialog__close', 'data-mdc-dialog-action': "close"})
        close_btn.appendChild(javascript.document.createTextNode('close'))
        header.appendChild(close_btn)

        content = maketag(
            'div', {'class': 'mdc-dialog__content'}, {'border-top': '1px solid lightgrey'})
        sur.appendChild(content)
        if self.children is not None:
            for child in self.children:
                content.appendChild(child.render())

        acts = maketag('div', {'class': 'mdc-dialog__actions'})
        sur.appendChild(acts)
        if self.actions is not None:
            for act in self.actions:
                acts.appendChild(act.render())

        e.appendChild(maketag('div', {'class': 'mdc-dialog__scrim'}))
        return e


"""
Dividers: by-LJ
"""



"""
Image-Lists: NO
"""


"""
Lists: by-LJ
"""

class ListView:
    def __init__(self, children):
        if children is not None:
            assert isinstance(children, (tuple, list))
            for child in children:
                assert hasattr(child, 'render') and callable(child.render)
        self.children = children

    def render(self):
        list = maketag('ul', {'class': 'mdc-list'})
        if self.children is not None:
            for child in self.children:
                child = child.render()
                list.appendChild(child)
        javascript.mdc.list.MDCList.new(list)
        return list

class ListTile:
    def __init__(self, title, subtitle=None, leading=None, trailing=None, href=None, color='blue', margin=None):
        assert isinstance(title, Text)
        if subtitle is not None:
            assert isinstance(subtitle, Text)
        if leading is not None:
            assert isinstance(leading, Icon)
        if trailing is not None:
            assert hasattr(trailing, 'render') and callable(trailing.render)
        self.title = title
        self.subtitle = subtitle
        self.leading = leading
        self.trailing = trailing
        self.href = href
        self.color = color
        self.margin=margin

    def render(self):
        re = maketag('a', {'href': f'{self.href}'}, style={'text-decoration': 'none', 'color': f'{self.color}'})
        if self.subtitle is not None:
            lt = maketag('li', {'class': 'mdc-list-item'}, style={'color': f'{self.color}'})
        else:
            lt = maketag('li', {'class': 'mdc-list-item'}, style={'color': f'{self.color}', 'align-items': 'center'})
        rip = maketag('span', {'class': 'mdc-list-item__ripple'})
        lt.appendChild(rip)

        if self.leading is not None:
            icon = maketag('i', {'class': 'material-icons mdc-list-item_graphic', 'aria-hidden': 'true'})
            icon.appendChild(javascript.document.createTextNode(self.leading.icon))
            lt.appendChild(icon)
        text_ = maketag('span', {'class': 'mdc-list-item__text'})

        if self.subtitle is not None:
            pri_text = maketag('span', {'class': 'mdc-list-item__primary-text'}, style={'color': f'{self.color}'})
            pri_text.appendChild(self.title.render())
            sec_text = maketag('span', {'class': 'mdc-list-item__secondary-text'}, style={'color': 'black'})
            sec_text.appendChild(self.subtitle.render())
            text_.appendChild(pri_text)
            text_.appendChild(sec_text)
        else:
            text_.appendChild(self.title.render())
        lt.appendChild(text_)
        re.appendChild(lt)
        if self.trailing is not None:
            gra = maketag('span', {'class': 'mdc-list-item--with-trailing-meta'}, style={'margin-left': 'auto', 'margin-block': 'auto', 'margin-right': f'{self.margin}'})
            gra.appendChild(self.trailing.render())
            lt.appendChild(gra)
        if self.href is not None:
            return re
        else:
            return lt


"""
Menus: by-LJ
"""
class PopupMenuButton:
    def __init__(self, icon=None, itemBuilder=None):
        if icon is not None:
            assert isinstance(icon, Icon)
        if itemBuilder is not None:
            assert isinstance(itemBuilder, (tuple, list))
            for item in itemBuilder:
                assert hasattr(item, 'render') and callable(item.render)
        self.icon = icon
        self.itemBuilder = itemBuilder

    def render(self):
        menu = maketag('div',
                       {'class': 'mdc-menu mdc-menu-surface mdc-menu-surface--is--open-below mdc-menu-surface--open'},
                       style={'display': 'flex', 'z-index': 'auto'})
        # javascript.mdc.menu.MDCMenu.new(menu)
        builder = maketag('ul',
                          {'class': 'mdc-list', 'role': 'menu', 'aria-hidden': 'true', 'aria-orientation': 'vertical',
                           'tabindex': '-1'})
        menu.appendChild(builder)
        if self.itemBuilder is not None:
            for item in self.itemBuilder:
                builder.appendChild(item.render())

        return menu

class PopupMenuItem:
    def __init__(self, child):
        assert hasattr(child, 'render') and callable(child.render)
        self.child = child

    def render(self):
        if isinstance(self.child, ListTile):
            return self.child.render()
        else:
            menuItem = maketag('li', {'class': 'mdc-list-item', 'role': 'menuitem'})
            rip = maketag('span', {'class': 'mdc-list-item__ripple'})
            menuItem.appendChild(rip)
            text = maketag('span', {'class': 'mdc-list-item__text'})
            text.appendChild(self.child.render())
            menuItem.appendChild(text)
        return menuItem

class PopupMenuDivider:
    def __init__(self, color=None):
        self.color = color

    def render(self):
        div = maketag('li', {'class': 'mdc-list-divider', 'role': 'separator'}, style={'background-color': f'{self.color}'})
        return div


"""
Navigation-Drawer: by 
"""


"""
Navigation-rail: NO
"""


"""
Progress Indicators
"""


"""
Radio-Buttons: by-WYN
"""
class RadioButton:
    def __init__(self, id, name):
        self.id = id
        self.name = name

    def render(self):
        e = maketag('div', {'class': 'mdc-form-field'})
        start = maketag('div', {'class': 'mdc-radio'})
        in_put = maketag('input', {'class': 'mdc-radio__native-control', 'type': 'radio', 'id': 'radio-1', 'name': 'radios',
                                   'aria-checked': 'false'})
        background = maketag('div', {'class': 'mdc-radio__background'})
        outer = maketag('div', {'class': 'mdc-radio__outer-circle'})
        inner = maketag('div', {'class': 'mdc-radio__inner-circle'})
        background.appendChild(outer)
        background.appendChild(inner)
        rip = maketag('div', {'class': "mdc-radio__ripple"})
        start.appendChild(in_put)
        start.appendChild(background)
        start.appendChild(rip)
        la = maketag('label', {'for': 'radio-1'})
        la.appendChild(self.name.render())
        e.appendChild(start)
        e.appendChild(la)
        javascript.mdc.radio.MDCRadio.new(e)
        return e


class TextField:
    def __init__(self, hinttext=None, onClick=None):
        assert (hinttext is None) or (isinstance(hinttext, str))
        if onClick is not None:
            assert callable(onClick)
        self.hinttext = hinttext
        self.onClick = onClick

    def render(self):
        if self.hinttext is None:
            self.hinttext = 'Hint text'
        e = maketag('label', {'class': 'mdc-text-field mdc-text-field--filled mdc-ripple-upgraded', 'id': 'labeltag'})
        if self.onClick is not None:
            e.bind('click', self.onClick)
        spanstart = maketag('span', {'class': 'mdc-text-field__ripple'})
        spanhint = maketag('span', {'class': 'mdc-floating-label', 'id': 'my-label-id'})
        spanhint.appendChild(javascript.document.createTextNode(self.hinttext))
        input = maketag('input', {'class': 'mdc-text-field__input', 'type': 'text', 'aria-labelledby': 'my-label-id'})
        spanend = maketag('span', {'class': 'mdc-line-ripple', 'id': 'spanendtag'})

        e.appendChild(spanstart)
        e.appendChild(spanhint)
        e.appendChild(input)
        e.appendChild(spanend)
        return e

"""
Sheets-Side: NO
"""


"""
Sheets-Bottom: NO
"""


"""
Sliders: by-LJS
"""
def make_svg(tag, attrs={}, style={}):
	xmlns = 'http://www.w3.org/2000/svg'
	elt = javascript.document.createElementNS(xmlns, tag)
	for k, v in attrs.items():
		elt.setAttribute(k, v)
	if len(style) > 0:
		style = ';'.join([f'{k}:{v}'for k, v in style.items()])
		elt.setAttribute('style', style)
	return elt

class Slider:
	def __init__(self, value, min, max, label, divisions=None, onChanged=None, tick_mark=False, disabled=False):
		if onChanged is not None:
			assert callable(onChanged)
		self.value = value
		self.min = min
		self.max = max
		self.label = label
		self.divisions = divisions
		self.onChanged = onChanged
		self.tick_mark = tick_mark
		self.disabled = disabled
		if self.divisions is None:
			self.tick_mark = False
	def render(self):
		e = maketag('div', {'class': 'mdc-slider'}, style={'width': '200px'})
		i = maketag('input', {'class': 'mdc-slider__input', 'type': 'range', 'min': f'{self.min}', 'max': f'{self.max}', 'value': f'{self.value}', 'name': 'volume', 'aria-label': 'Continuous slider demo'})
		if self.divisions is not None:
			add_class(e, 'mdc-slider--discrete')
			i = maketag('input', {'class': 'mdc-slider__input', 'type': 'range', 'min': f'{self.min}', 'max': f'{self.max}', 'value': f'{self.value}', 'name': 'volume', 'step': f'{self.divisions}', 'aria-label': 'Discrete slider demo'})
			if self.tick_mark:
				add_class(e, 'mdc-slider--tick-marks')
				i = maketag('input', {'class': 'mdc-slider__input', 'type': 'range', 'min': f'{self.min}', 'max': f'{self.max}', 'value': f'{self.value}', 'name': 'volume', 'step': f'{self.divisions}', 'aria-label': 'Discrete slider with tick marks demo'})
		e.appendChild(i)
		track = maketag('div', {'class': 'mdc-slider__track'})
		e.appendChild(track)
		inactive = maketag('div', {'class': 'mdc-slider__track--inactive'})
		active = maketag('div', {'class': 'mdc-slider__track--active'})
		track.appendChild(inactive)
		track.appendChild(active)
		active_fill = maketag('div', {'class': 'mdc-slider__track--active_fill'})
		active.appendChild(active_fill)
		if self.tick_mark:
			tick_marks = maketag('div', {'class': 'mdc-slider__tick-marks'})
			track.appendChild(tick_marks)
			for _ in range(6):
				tick_marks.appendChild(maketag('div', {'class': 'mdc-slider__tick-mark--active'}))
			for _ in range(5):
				tick_marks.appendChild(maketag('div', {'class': 'mdc-slider__tick-mark--inactive'}))

		thumb = maketag('div', {'class': 'mdc-slider__thumb'})
		e.appendChild(thumb)
		if self.divisions is not None:
			value_indicator_container = maketag('div', {'class': 'mdc-slider__value-indicator-container', 'aria-hidden': 'true'})
			thumb.appendChild(value_indicator_container)
			value_indicator = maketag('div', {'class': 'mdc-slider__value-indicator'})
			value_indicator_container.appendChild(value_indicator)
			value_indicator_text = maketag('span', {'class': 'mdc-slider__value-indicator-text'})
			value_indicator.appendChild(value_indicator_text)
			value_indicator_text.appendChild(javascript.document.createTextNode('50'))
		thumb_knob = maketag('div', {'class': 'mdc-slider__thumb-knob'})
		thumb.appendChild(thumb_knob)
		if self.disabled:
			add_class(e, 'mdc-slider--disabled')
		javascript.mdc.slider.MDCSlider.new(e)
		return e

class RangeSlider:
	def __init__(self, values, min, max, labels, divisions=None, onChanged=None, tick_mark=False, disabled=False):
		if onChanged is not None:
			assert callable(onChanged)
		self.values = values
		self.min = min
		self.max = max
		self.labels = labels
		self.divisions = divisions
		self.onChanged = onChanged
		self.tick_mark = tick_mark
		self.disabled = disabled
		if self.divisions is None:
			self.tick_mark = False
	def render(self):
		e = maketag('div', {'class': 'mdc-slider mdc-slider--range'}, style={'width': '200px'})
		start = maketag('input', {'class': 'mdc-slider__input', 'type': "range", 'min': f'{self.min}', 'max': f'{self.max}', 'value': f'{self.values[0]}', 'name': 'rangeStart', 'aria-label': 'Continuous range slider demo'})
		end = maketag('input', {'class': 'mdc-slider__input', 'type': "range", 'min': f'{self.min}', 'max': f'{self.max}', 'value': f'{self.values[1]}', 'name': 'rangeEnd', 'aria-label': 'Continuous range slider demo'})
		if self.divisions is not None:
			add_class(e, 'mdc-slider--discrete')
			start = maketag('input', {'class': 'mdc-slider__input', 'type': "range", 'min': f'{self.min}', 'max': f'{self.max}', 'value': f'{self.values[0]}',
							'step': f'{self.divisions}', 'name': 'rangeStart', 'aria-label': 'Discrete range slider demo'})
			end = maketag('input', {'class': 'mdc-slider__input', 'type': "range", 'min': f'{self.min}', 'max': f'{self.max}', 'value': f'{self.values[1]}',
						  'step': f'{self.divisions}', 'name': 'rangeEnd', 'aria-label': 'Discrete range slider demo'})
			if self.tick_mark:
				add_class(e, 'mdc-slider--tick-marks')
				start = maketag('input', {'class': 'mdc-slider__input', 'type': "range", 'min': f'{self.min}', 'max': f'{self.max}',
								'value': f'{self.values[0]}',
								'step': f'{self.divisions}', 'name': 'rangeStart',
								'aria-label': 'Discrete range slider with tick marks demo'})
				end = maketag('input', {'class': 'mdc-slider__input', 'type': "range", 'min': f'{self.min}', 'max': f'{self.max}',
							  'value': f'{self.values[1]}',
							  'step': f'{self.divisions}', 'name': 'rangeEnd',
							  'aria-label': 'Discrete range slider with tick marks demo'})
		e.appendChild(start)
		e.appendChild(end)
		track = maketag('div', {'class': 'mdc-slider__track'})
		e.appendChild(track)
		inactive = maketag('div', {'class': 'mdc-slider__track--inactive'})
		active = maketag('div', {'class': 'mdc-slider__track--active'})
		track.appendChild(inactive)
		track.appendChild(active)
		active_fill = maketag('div', {'class': 'mdc-slider__track--active_fill'})
		active.appendChild(active_fill)

		if self.tick_mark:
			tick_marks = maketag('div', {'class': 'mdc-slider__tick-marks'})
			track.appendChild(tick_marks)
			for _ in range(6):
				tick_marks.appendChild(maketag('div', {'class': 'mdc-slider__tick-mark--active'}))
			for _ in range(5):
				tick_marks.appendChild(maketag('div', {'class': 'mdc-slider__tick-mark--inactive'}))

		thumb = maketag('div', {'class': 'mdc-slider__thumb'})
		e.appendChild(thumb)

		if self.divisions is not None:
			value_indicator_container = maketag('div', {'class': 'mdc-slider__value-indicator-container', 'aria-hidden': 'true'})
			thumb.appendChild(value_indicator_container)
			value_indicator = maketag('div', {'class': 'mdc-slider__value-indicator'})
			value_indicator_container.appendChild(value_indicator)
			value_indicator_text = maketag('span', {'class': 'mdc-slider__value-indicator-text'})
			value_indicator.appendChild(value_indicator_text)
			value_indicator_text.appendChild(javascript.document.createTextNode('20'))

		thumb_knob = maketag('div', {'class': 'mdc-slider__thumb-knob'})
		thumb.appendChild(thumb_knob)
		thumb2 = maketag('div', {'class': 'mdc-slider__thumb'})
		e.appendChild(thumb2)

		if self.divisions is not None:
			value_indicator_container2 = maketag('div', {'class': 'mdc-slider__value-indicator-container', 'aria-hidden': 'true'})
			thumb2.appendChild(value_indicator_container2)
			value_indicator2 = maketag('div', {'class': 'mdc-slider__value-indicator'})
			value_indicator_container2.appendChild(value_indicator2)
			value_indicator_text2 = maketag('span', {'class': 'mdc-slider__value-indicator-text'})
			value_indicator2.appendChild(value_indicator_text2)
			value_indicator_text2.appendChild(javascript.document.createTextNode('50'))

		thumb_knob2 = maketag('div', {'class': 'mdc-slider__thumb-knob'})
		thumb2.appendChild(thumb_knob2)
		if self.disabled:
			add_class(e, 'mdc-slider--disabled')
		javascript.mdc.slider.MDCSlider.new(e)
		return e


"""
Snackbars
"""


"""
Switches: by-LZG
"""
class Switch:
    def __init__(self, onChanged, value=False, activeColor=Colors.black, id='switch'):
        assert isinstance(onChanged, bool)
        assert isinstance(value, bool)
        assert isinstance(activeColor, str)
        self.onChanged = onChanged
        self.value = value
        self.activeColor = activeColor
        assert isinstance(id, str)
        if id == 'switch':
            self.switchId = 'switch-' + str(time.time())
        else:
            self.switchId = id

    def render(self):
        e = maketag('div', {'class': 'mdc-touch-target-wrapper'}, {'margin-top': '10px'})
        button = maketag('button', {'id': self.switchId,
                                    'class': 'mdc-switch mdc-switch--selected' if self.value
                                    else 'mdc-switch mdc-switch--unselected',
                                    'type': 'button',
                                    'role': 'switch', 'aria-checked': 'true' if self.value else 'false'},
                         {'color': self.activeColor})
        # button.bind('mouseup', self.onClick)
        if not self.onChanged:
            button.setAttribute('disabled', 'true')
        e.appendChild(button)
        mdcSwitchTrack = maketag('div', {'class': 'mdc-switch__track'})
        button.appendChild(mdcSwitchTrack)
        mdcSwitchHandleTrack = maketag('div', {'class': 'mdc-switch__handle-track'})
        button.appendChild(mdcSwitchHandleTrack)
        mdcSwitchHandle = maketag('div', {'class': 'mdc-switch__handle'})
        mdcSwitchHandleTrack.appendChild(mdcSwitchHandle)
        mdcSwitchShadow = maketag('div', {'class': 'mdc-switch__shadow'})
        mdcSwitchHandle.appendChild(mdcSwitchShadow)
        mdcElevationOverlay = maketag('div', {'class': 'mdc-elevation-overlay'})
        mdcSwitchShadow.appendChild(mdcElevationOverlay)
        mdcSwitchRipple = maketag('div', {'class': 'mdc-switch__ripple'})
        mdcSwitchHandle.appendChild(mdcSwitchRipple)
        mdcSwitchIcons = maketag('div', {'class': 'mdc-switch__icons'})
        mdcSwitchHandle.appendChild(mdcSwitchIcons)
        # todo: svg未正确作用
        svg1 = _make_svg('svg', {'class': 'mdc-switch__icon mdc-switch__icon--on', 'viewBox': '0 0 24 24'})
        path1 = _make_svg('path', {'d': 'M19.69,5.23L8.96,15.96l-4.23-4.23L2.96,13.5l6,6L21.46,7L19.69,5.23z'})
        svg2 = _make_svg('svg', {'class': 'mdc-switch__icon mdc-switch__icon--off', 'viewBox': '0 0 24 24'})
        path2 = _make_svg('path', {'d': 'M20 13H4v-2h16v2z'})
        mdcSwitchIcons.appendChild(svg1)
        mdcSwitchIcons.appendChild(svg2)
        svg1.appendChild(path1)
        svg2.appendChild(path2)
        # label = maketag('label', {'for': self.switchId})
        # labelText = javascript.document.createTextNode('off/on')
        # e.appendChild(label)
        # label.appendChild(labelText)
        # 绑定点击切换开关控制
        javascript.mdc.switchControl.MDCSwitch.new(button)
        return e


"""
Tabs: by-LZW+YYX
"""
'''
by-LZW
'''
class TabButton:
    def __init__(self, icon, text):
        self.icon = icon
        self.text = text

    def render(self, parent, tabindex, body):
        e = maketag('button',
                    {'class': 'mdc-tab mdc-tab--active', 'role': 'tab', 'aria-selected': 'true', 'tabindex': tabindex})
        a1 = maketag('span', {'class': 'mdc-tab__content'})
        e.appendChild(a1)
        a1.appendChild(self.icon.render())
        a1.appendChild(self.text.render())
        if (tabindex == 0):
            a2 = maketag('span', {'class': 'mdc-tab-indicator mdc-tab-indicator--active'})
        else:
            a2 = maketag('span', {'class': 'mdc-tab-indicator'})
        a3 = maketag('span', {'class': 'mdc-tab-indicator__content mdc-tab-indicator__content--underline'})
        a2.appendChild(a3)
        e.appendChild(a2)
        a4 = maketag('span', {'class': 'mdc-tab__ripple'})
        e.appendChild(a4)
        parent.appendChild(e)

        def click(ev):
            b1 = javascript.document.querySelector('.mdc-tab-bar')
            print(b1)
            d1 = b1.parentNode.parentNode.lastChild
            d1.parentNode.removeChild(d1)
            b1.parentNode.parentNode.appendChild(body.render())

        e.bind('click', click)

        return e

class TabBar:
    def __init__(self, children, body):
        self.children = children
        self.body = body

    def render(self):
        scafflod_height = javascript.document.documentElement.clientHeight.data()
        e = maketag('div', style={'display': 'flex', 'flex-flow': 'column', 'height': f'{scafflod_height}px'})
        header = maketag('header', {'class': 'mdc-top-app-bar mdc-top-app-bar--fixed'},
                         style={'flex': '0 1 auto', 'background-color': '#D3A4FF'})
        e.appendChild(header)
        main = maketag('header', {'class': 'mdc-top-app-bar--fixed-adjust'},
                       style={'flex': '1 1 auto'})
        main.appendChild(self.body[0].render())
        e.appendChild(main)
        e1 = maketag('div', {'class': 'mdc-tab-bar', 'role': 'tablist'}, style={'width': '320px'})
        header.appendChild(e1)
        a1 = maketag('div', {'class': 'mdc-tab-scroller'})
        e1.appendChild(a1)
        a2 = maketag('div', {'class': 'mdc-tab-scroller__scroll-area'})
        a1.appendChild(a2)
        a3 = maketag('div', {'class': 'mdc-tab-scroller__scroll-content'})
        a2.appendChild(a3)
        for i in range(len(self.children)):
            if i == 0:
                a3.appendChild(self.children[i].render(a3, 0, self.body[i]))
            else:
                a3.appendChild(self.children[i].render(a3, -1, self.body[i]))
        # self.appBar.render(header)
        # self.body.render(main)
        self.topAppBar = javascript.mdc.topAppBar.MDCTopAppBar.new(e)
        javascript.mdc.tabBar.MDCTabBar.new(e1)
        return e

'''
by-YYX
'''
# class Tab:
#     def __init__(self, text=None, icon=None):
#         if text is not None:
#             assert hasattr(text, 'render') and callable(text.render)
#         if icon is not None:
#             assert hasattr(icon, 'render') and callable(icon.render)
#         self.text = text
#         self.icon = icon
#
#     def render(self, parent):
#         if True:
#             e = maketag('button', {'class': 'mdc-tab mdc-tab--active', 'role': 'tab'})
#             e1 = maketag('span', {'class': 'mdc-tab__content'})
#             e.appendChild(e1)
#             e2 = maketag('span', {'class': 'mdc-tab-indicator mdc-tab-indicator--active'})
#             e.appendChild(e2)
#             e3 = maketag('span', {'class': 'mdc-tab-indicator__content mdc-tab-indicator__content--underline'})
#             e2.appendChild(e3)
#             e4 = maketag('span', {'class': 'mdc-tab__ripple'})
#             e.appendChild(e4)
#
#
#         if self.icon is not None:
#             icon = self.icon.render(e1)
#             add_class(icon, 'mdc-tab__icon material-icons')
#         if self.text is not None:
#             text = self.text.render(e1)
#             add_class(text, 'mdc-tab__text-label')
#         parent.appendChild(e)
#         return e

# class TabBar:
#     def __init__(self, tabs=None):
#         if tabs is not None:
#             for tmp in tabs:
#                 assert hasattr(tmp, 'render') and callable(tmp.render)
#                 self.tabs = tabs
#
#     def render(self, parent):
#         e = maketag('div', {'class': 'mdc-tab-bar', 'role': 'tablist'})
#         if True:
#             e1 = maketag('div', {'class': 'mdc-tab-scroller'})
#             e.appendChild(e1)
#             e2 = maketag('div', {'class': 'mdc-tab-scroller__scroll-area'})
#             e1.appendChild(e2)
#             e3 = maketag('div', {'class': 'mdc-tab-scroller__scroll-content'})
#             e2.appendChild(e3)
#
#         if self.tabs is not None:
#             for tmp in self.tabs:
#                 tmp.render(e3)
#         parent.appendChild(e)
#         return e


"""
Text-Fields: by-HLH
"""
class TextFormField:
    '''
    inputType == text : 用于输入文本
    inputType == password : 用于输入密码
    '''

    def __init__(self, inputType, text='', color=None):
        self.inputType = inputType
        # if color is not None:
        #     assert hasattr(color, 'render') and callable(color.render)
        self.color = color
        self.text = text

    def render(self):
        e = maketag('div', {
            'class': 'mdc-text-field mdc-text-field--outlined mdc-text-field--textarea mdc-text-field--no-label'})
        # s = maketag('header',{'class':'mdc-text-field mdc-notched-outline'})
        end = maketag('header', {'class': 'mdc-text-field mdc-notched-input'})
        # e.appendChild(s)
        e.appendChild(end)

        if self.inputType == 'text':
            t = maketag('input', {'class': 'mdc-text-field--textarea', 'type': 'text', 'placeholder': f'{self.text}'}, style={'color': f'{self.color}'})
        if self.inputType == 'password':
            t = maketag('input', {'class': 'mdc-text-field--textarea', 'type': 'password', 'placeholder': f'{self.text}'})
        end.appendChild(t)

        h = maketag('div', {'class': 'mdc-text-field-helper-text', 'id': 'my-helper-id', 'aria-hidden': 'true'})
        end.appendChild(h)

        # e = maketag('textarea',{'class':'mdc-text-field__input'})
        # e.appendChild(container)

        return e


"""
Time-Pickers: NO
"""


"""
Tooltips: by-LJ
"""
class Tooltip:
    def __init__(self, message=None, child=None):
        self.message = message
        self.child = child

    def render(self):
        e = maketag('div', {'class':'mdc-tooltip-wrapper--rich'})
        but = maketag('button', {'class': 'mdc-button mdc-ripple-upgraded', 'aria-describedby':'tt0'})
        rip = maketag('div', {'class': 'mdc-button__ripple'})
        label = maketag('span',{'class': 'mdc-button__label'})
        label.appendChild(javascript.document.createTextNode('Button'))
        but.appendChild(rip)
        but.appendChild(label)
        e.appendChild(but)

        me = maketag('div', {'id': 'tt0', 'class': 'mdc-tooltip mdc-tooltip--rich', 'role': 'tooltip', 'aria-hidden': 'true'},
                    style={'top': '40px', 'width': '320px','left': '81.2px'})
        sur = maketag('div', {'class': 'mdc-tooltip__surface mdc-tooltip__surface-animation'}, style={'transform-origin': 'left top'})
        if self.message is not None:
            cont = maketag('p', {'class': 'mdc-tooltip__content'})
            cont.appendChild(self.message.render())
            sur.appendChild(cont)
        me.appendChild(sur)
        e.appendChild(me)
        javascript.mdc.tooltip.MDCTooltipFoundation.new(e)
        return e

